import $service from '../../../../service'
const AgoraMiniappSDK = require("agora-miniapp-sdk");
const max_user = 10
const app = getApp();


Component({
  data: {
    pusher: null,
    playerList: [],
    media: [],
    config: null,
    getPusherStream: '',
    getDoctorStream: []
  },
  lifetimes:{
    async ready() {
      console.log('视频i聊天',JSON.parse($service.getStore('userInfo')).type)
      this.setData({
        config: JSON.parse($service.getStore(JSON.parse($service.getStore('userInfo')).type === 'D' ? 'tencentConfigD' : 'tencentConfigP'))
      })
      console.log('this.setData',this.data.config)
      this.client = null
      try {
        // init agora channel
        console.log(this.data.config)
        const {userId, room} = this.data.config
        const url = await this.initAgoraChannel(userId, room)
        console.log(`channel: ${room}, uid: ${userId}, pushing ${url}`);
        let ts = new Date().getTime();
        this.addMedia(0, userId, url, {
          key: ts
        });
        // }
      } catch (e) {
        console.log(e, 123123123123123)
        wx.showToast({
          title: `客户端初始化失败`,
          icon: 'none',
          duration: 5000
        });
      }
    },
    detached: function () {
    },
  },

  methods: {
    /**
     * 获取流
     */
    // 自己
    async getPusherStream() {
      let media = this.data.media || [];
      let pusher = media.find(item => {
        return item.type === 0
      });
      console.log('pusher',pusher)
      return pusher ? pusher.url : '';
    },
    // 医生
    async getDoctorStream() {
        let media = this.data.media || [];
        let doctor = media.filter(item => {
            return item.type === 1
        });
      console.log('doctor',doctor)
        return doctor
    },
    /**
   * 初始化sdk推流
   */
  async initAgoraChannel(userId, room) {
    this.client = new AgoraMiniappSDK.Client()
    // set log level
    AgoraMiniappSDK.LOG.setLogLevel(-1);
    //subscribe stream events
    this.subscribeEvents();
    await this.client.init(this.data.config.appId)
    await this.client.setRole('broadcaster')
    await this.client.join(this.data.config.sig, room, userId)
    let url = ''
    // if (this.isBroadcaster()) {
      url = await this.client.publish(url);
    // }
    this.videoRecord(1)
    return url
  },

  // 视频录制 1开始录制 2结束录制
   async videoRecord(type) {
    if (JSON.parse($service.getStore('userInfo')).type === 'D') {
      await app.http.videoStartOrEnd({
        "cname": this.data.config.room,
        "status": type
      }).catch(err => {
        wx.showToast({
          title: err.msg,
          icon: 'none',
          duration: 5000
        });
      })
    }
  },


  async reinitAgoraChannel(uid, channel) {
    this.client = new AgoraMiniappSDK.Client({
      mode: 'rtc',
      codec: 'h264' // Web端如果使用h264，这里需要相应修改
    })
    AgoraMiniappSDK.LOG.setLogLevel(-1);
    this.subscribeEvents();
    let uids = this.data.media.map(item => {
      return item.uid;
    });
    await this.client.init(this.data.config.appId)
    await this.client.setRole('broadcaster');
    await this.client.rejoin(undefined, channel, uid, uids)
    let url = ''
    url = await this.client.publish()
    return url
  },

  addMedia(mediaType, uid, url, options) {
    console.log(`add media ${mediaType} ${uid} ${url}`);
    let media = this.data.media || [];
    if (mediaType === 0) {
      //pusher
      media.splice(0, 0, {
        key: options.key,
        type: mediaType,
        uid: `${uid}`,
        holding: false,
        url: url,
        left: 0,
        top: 0,
        width: 0,
        height: 0
      });
    } else {
      //player
      media.push({
        key: options.key,
        rotation: options.rotation,
        type: mediaType,
        uid: `${uid}`,
        holding: false,
        url: url,
        left: 0,
        top: 0,
        width: 0,
        height: 0
      });
    }
    return this.refreshMedia(media);
  },
  /**
   * 注册stream事件
   */
  subscribeEvents() {
    /**
     * fired when new stream join the channel
     */
    this.client.on("stream-added", async e => {
      console.log('医生加入了', e)
      let uid = e.uid;
      const ts = new Date().getTime();
      /**
       * subscribe to get corresponding url
       */
      const { url, rotation } = await this.client.subscribe(uid);
      let media = this.data.media || [];
      let matchItem = null;
      for (let i = 0;i < media.length;i++) {
        let item = this.data.media[i];
        if (item.uid == uid) {
          matchItem = item;
          break;
        }
      }
      if (!matchItem) {
        this.addMedia(1, uid, url, {
          key: ts,
          rotation: rotation
        })
      } else {
        this.updateMedia(matchItem.uid, {
          url: url,
          key: ts,
        });
      }
    });

    /**
     * remove stream when it leaves the channel
     */
    this.client.on("stream-removed", e => {
      this.removeMedia(e.uid);
    });

    /**
     * when bad thing happens - we recommend you to do a
     * full reconnect when meeting such error
     * it's also recommended to wait for few seconds before
     * reconnect attempt
     */
    this.client.on("error", err => {
      let errObj = err || {};
      let code = errObj.code || 0;
      let reason = errObj.reason || "";
      console.log(`error: ${code}, reason: ${reason}`);
      if (code === 501 || code === 904) {
        this.reconnect();
      }
    });

    /**
     * there are cases when server require you to update
     * player url, when receiving such event, update url into
     * corresponding live-player, REMEMBER to update key property
     * so that live-player is properly refreshed
     * NOTE you can ignore such event if it's for pusher or happens before
     * stream-added
     */
    this.client.on('update-url', e => {
      let uid = e.uid;
      let url = e.url;
      let ts = new Date().getTime();
      if (uid == this.data.config.userId) {
        console.log(`ignore update-url`);
      } else {
        this.updateMedia(uid, {
          url: url,
          key: ts,
        });
      }
    });

    this.client.on("token-privilege-will-expire", () => {
      console.log("当前 token 即将过期，请更新 token");
    });

    this.client.on("token-privilege-did-expire", () => {
      console.log("当前 token 已过期，请更新 token 并重新加入频道");
    });
  },

   /**
   * remove media from view
   */
  removeMedia(uid) {
      let media = this.data.media || [];
      media = media.filter(item => {
        return `${item.uid}` !== `${uid}`
      });

      if (media.length !== this.data.media.length) {
        this.refreshMedia(media);
      } else {
        return Promise.resolve();
      }
    },
  /**
   * update media object
   * the media component will be fully refreshed if you try to update key
   * property.
   */
  updateMedia(uid, options) {
    let media = this.data.media || [];
    let changed = false;
    for (let i = 0;i < media.length;i++) {
      let item = media[i];
      if (`${item.uid}` === `${uid}`) {
        media[i] = Object.assign(item, options);
        changed = true;
        console.log(`after update media ${uid} ${JSON.stringify(item)}`)
        break;
      }
    }

    if (changed) {
      return this.refreshMedia(media);
    } else {
      console.log(`media not changed: ${JSON.stringify(media)}`)
      return Promise.resolve();
    }
  },


   /**
   * call setData to update a list of media to this.data.media
   * this will trigger UI re-rendering
   */
  refreshMedia(media) {
    return new Promise((resolve) => {
      for (let i = 0;i < media.length;i++) {
        if (i < max_user) {
          //show
          media[i].holding = false;
        } else {
          //hide
          media[i].holding = true;
        }
      }
      console.log('刷新了')
      if (media.length > max_user) {
        wx.showToast({
          title: `由于房内人数超过${max_user}人，部分视频未被加载显示`,
        });
      }

      console.log(`updating media: `, media);
      this.setData({
        media: media
      }, () => {
        console.log('media updated');
        this.setData({
          getPusherStream: this.getPusherStream(),
          getDoctorStream: this.getDoctorStream()
        }, () => {
          resolve()
        })
      });

    });
  },

   /**
   * reconnect when bad things happens...
   */
  async reconnect() {
    wx.showToast({
      title: `尝试恢复链接...`,
      icon: 'none',
      duration: 5000
    });
    // always destroy client first
    // *important* miniapp supports 5 websockets maximum at same time
    // do remember to destroy old client first before creating new ones
    await this.client.destroy();
    this.reconnectTimer = setTimeout(async () => {
      const {userId, room} = this.data.config
      try {
        const url = await this.reinitAgoraChannel(userId, room)
        let ts = new Date().getTime();
          if (this.hasMedia(0, userId)) {
            this.updateMedia(userId, {
              url: url,
              key: ts,
            });
          } else {
            // pusher not exists in media list
            console.log(`pusher not yet exists when rejoin...adding`);
            this.addMedia(0, userId, url, {
              key: ts
            });
          }
        // }
      } catch (e) {
        console.log(`reconnect failed: ${e}`);
        // remember control max reconnect times
        return this.reconnect();
      }
    }, 1 * 1000);
  },

   /**
   * check if current media list has specified uid & mediaType component
   */
  hasMedia(mediaType, uid) {
    let media = this.data.media || [];
    return media.filter(item => {
      return item.type === mediaType && item.uid == uid
    }).length > 0
  },

  /**
   * return player component via uid
   */
  getPlayerComponent(uid) {
    return this.selectComponent(`#rtc-player-${uid}`);
  },

  /**
   * return pusher component
   */
  getPusherComponent() {
    return this.selectComponent(`#rtc-pusher`);
  },



 // 请保持跟 wxml 中绑定的事件名称一致
 _pusherStateChangeHandler(event) {
    // this.TRTC.pusherEventHandler(event)
  },
  _pusherNetStatusHandler(event) {
    // this.TRTC.pusherNetStatusHandler(event)
  },
  _playerStateChange(event) {
    // this.TRTC.playerEventHandler(event)
  },
  _playerNetStatus(event) {
    // this.TRTC.playerNetStatus(event)
  },

  exitRoom() {
    this.client.leave()
    this.videoRecord(2)
    this.setData({
      media: []
    })
    this.setData({
      getPusherStream: '',
      getDoctorStream: []
    })

  },
    // *************



    openSetting() {
      return new Promise((resolve, reject) => {
        wx.showModal({
          title: '温馨提示',
          content: '请授权微信小程序麦克风与摄像头权限，以使用视频功能',
          success: (res) => {
            if (res.confirm) {
              wx.openSetting({
                success: function (res) {
                  console.log('打开权限设置页面', res)
                  // const authSettingObj = res.authSetting
                  return resolve(true)
                },
              })
            } else {
              return reject()
            }
          },
          fail: (err) => {
            return reject()
          },
        })
      })
    },
    checkPermisson() {
      return new Promise((resolve, reject) => {
        wx.getSetting({
          success: async (res) => {
            const authSettingObj = res.authSetting
            console.log(authSettingObj)
            if (authSettingObj['scope.camera'] === true && authSettingObj['scope.record'] === true) {
              // 当前已经有权限了
              console.log('当前已经有视频录音权限了')
              return resolve(true)
            } else if (authSettingObj['scope.camera'] === false || authSettingObj['scope.record'] === false) {
              // 之前问过权限，但是拒绝了
              console.log('之前问过权限，但是拒绝了')
              // 打开setting
              await this.openSetting()
              try {
                return resolve(true)
              } catch {
                return reject(false)
              }
            } else {
              // 还没问过权限
              console.log('还没问过权限')
              // 去请求授权
              wx.authorize({
                success: (res) => {
                  return resolve(true)
                },
                fail: async (err) => {
                  // 拒绝授权了
                  // 打开setting
                  try {
                    await this.openSetting()
                    return resolve(true)
                  } catch {
                    return reject(false)
                  }
                },
              })
            }
          },
        })
      })
    }
  }
})
